﻿using System;
using System.Globalization;
using System.Threading;

namespace Cherry.Agile.RpcService
{
    /// <summary>
    /// 通信服务处理模块V1.0版本
    /// 此协议版本制定于2010年8月
    /// Create by：赖国欣
    /// 协议内容请参考相关文档（通信组件公共模块）
    /// </summary>
    public class ServiceProcessorV10 : IServiceProcessor
    {
        public void Process(ProcessContext context)
        {
            ServiceConfigInfo config = ServiceConfigManager.ServiceConfig;
            
            BufferReader reader = context.Reader;
            BufferWriter writer = new BufferWriter();

            try
            {
                //处理语言
                short lcid = reader.ReadInt16();
                if (config.SupportedLanguage.Contains(lcid))
                {
                    CultureInfo culture = new CultureInfo(lcid);
                    Thread.CurrentThread.CurrentCulture = culture;
                    Thread.CurrentThread.CurrentUICulture = culture;
                    context.Culture = culture;
                }
                else
                {
                    context.ResponseCode = ResponseCode.LanguageNotSpported;
                }

                ////读取Token
                //long token = context.Reader.ReadInt64();
                //context.Token = token;

                //读保留位 
                reader.ReadBytes(2);

                //int requestUnitLimit = 100; //请求单元上限
                writer.Write(new byte[] { 0, 0, 0, 0 }); //写入保留位

                while (reader.RemainLength > 0)
                {
                    context.BusinessCode = reader.ReadInt16();//读业务码
                    context.FunctionCode = reader.ReadInt16();//读功能码
                    context.RequestCode = ((Int32)context.BusinessCode) << 16 | ((int)context.FunctionCode);
                    context.WriteTrace(string.Format("BusinessCode:{0},FunctionCode:{1},RequestCode:{2}", context.BusinessCode, context.FunctionCode, context.RequestCode));

                    int length = reader.ReadInt32(); //读请求单元长度
                    byte[] reqUnitBuf = reader.ReadBytes(length);//请求单元数据
                    context.Reader = new BufferReader(reqUnitBuf); //初始化单元请求数据读取器
                    context.Writer = new BufferWriter();//初始化单元数据响应写入器

                    if (config.ProcessModuleList.ContainsKey(context.RequestCode))
                    {
                        try
                        {
                            ProcessModuleInfo module = config.ProcessModuleList[context.RequestCode];
                            //加载验证模块
                            if (module.RequireValidate && config.AuthenModule != null)
                            {
                                config.AuthenModule.Process(context);
                                if (context.Authendicated == false)
                                {
                                    throw new Exception("not authen.");
                                }
                            }
                            //加载新通知模块
                            if (config.CheckNewNotifyModule != null)
                            {
                                //config.CheckNewNotifyModule.Process(context);
                            }
                            module.Process(context);
                        }
                        catch (Exception ex)
                        {
                            context.ResponseCode = ResponseCode.AppUnhandledException;
                            throw;
                            //throw new ServiceProcessException(context.ResponseCode,"",ex)
                        }

                    }
                    else
                    {
                        context.ResponseCode = ResponseCode.RequestCodeNotSupported;
                    }
                }

                //把原来的请求数据保存到context里
                context.Reader = reader;
            }
            catch (Exception ex)
            {
                context.ResponseCode = ResponseCode.SystemError;
                context.WriteTrace(string.Format("%PT%,{0},{1}", ex.Message, ex.StackTrace));
                throw;
            }
            finally
            {
                //写响应
                BufferWriter writerRet = new BufferWriter();
                writerRet.Write(new byte[] { 1, 1 });//写入版本号
                writerRet.Write((int)context.ResponseCode);
                writerRet.Write(context.BusinessCode);
                writerRet.Write(context.FunctionCode);
                writerRet.Write(context.Writer.ToArray());
                context.Writer = writerRet;
            }
            //return 0;
        }
    }
}
